﻿using Learn.Infraestrutura.Attr;
using Learn.Infraestrutura.Dto.Request;
using Learn.Infraestrutura.Dto.Request.Right;
using Learn.Infraestrutura.Dto.Response;
using Learn.Infraestrutura.Dto.Response.Login;
using Learn.Infraestrutura.Dto.Response.Right;
using Learn.Infraestrutura.EFCore;
using Learn.Infraestrutura.IOC;
using Learn.Infraestrutura.Tools;
using Learn.Service.Interface;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;


namespace Learn.Service.Instance
{

    /// <summary>
    /// 权限模块
    /// </summary>
    [Inject_]
    public class Right_Service : Base_Service, I_Right_Service
    {
        private readonly Right_IOC _right_IOC;

        public Right_Service(Right_IOC right_IOC)
        {
            _right_IOC = right_IOC;

        }
        /// <summary>
        /// 获取所有权限
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Api_Result Get_Rights(Right_Request_Dto dto)
        {
            
            var rights = _right_IOC._sys_Right_EFCore.QueryAll(d=>d.RisBan==dto.isBan&&d.RisPublish==dto.isPublish).ToList();

            //顶级
            var root = rights.Where(d => d.RparentRid == null||d.RparentRid=="").OrderBy(d => d.Rno).ToList();
            //子级用递归来获取
            List<Right_Response_Dto> data = new List<Right_Response_Dto>();
            root.ForEach(d =>
            {
                data.Add(new Right_Response_Dto
                {
                    id = d.Rid,
                    name = d.Rname,
                    icon = d.Ricon,
                    explain = d.Rexplain,
                    isBan = d.RisBan,
                    isMenu = d.RisMenu,
                    isPublic = d.RisPublic,
                    isPublish = d.RisPublish,
                    createtime = d.RcreateTime.ToString(),
                    url = d.Rurl,
                    no = d.Rno,
                    children = Get_Right_Children(d.Rid, rights)
                });
            });
            return Result(1, "ok", data: data);
        }
        /// <summary>
        /// 获取子集权限
        /// </summary>
        /// <param name="rid"></param>
        /// <param name="rights"></param>
        /// <returns></returns>
        private List<Right_Response_Dto> Get_Right_Children(string rid, List<SysRights> rights)
        {
            var children = rights.Where(d => d.RparentRid == rid).OrderBy(d=>d.Rno).ToList();
            List<Right_Response_Dto> data = new List<Right_Response_Dto>();
            children.ForEach(d =>
            {
                data.Add(new Right_Response_Dto
                {
                    id = d.Rid,
                    name = d.Rname,
                    icon = d.Ricon,
                    explain = d.Rexplain,
                    isBan = d.RisBan,
                    isMenu = d.RisMenu,
                    isPublic = d.RisPublic,
                    isPublish = d.RisPublish,
                    createtime = d.RcreateTime.ToString(),
                    url = d.Rurl,
                    no = d.Rno,
                    children = Get_Right_Children(d.Rid, rights)
                });
            });

            return data;
        }



        /// <summary>
        /// 获取用户菜单
        /// </summary>
        /// <param name="uid"></param>
        /// <returns></returns>
        public Api_Result Get_User_Menus(string uid)
        {
            //得到用户的权限
            var userRights = _right_IOC._sys_User_Right_EFCore.QueryAll(d => d.Uruid == uid).ToList();
            //得到上述权限的ID  此处的获取是直接从内存中获取 所以速度很快
            var rids = userRights.Select(d => d.Urrid).ToList();
            //得到权限数据
            var rights = _right_IOC._sys_Right_EFCore.QueryAll(d => rids.Contains(d.Rid) && d.RisBan == 0&&d.RisMenu==1).ToList();

            List<User_Menu_Response_Dto> data = new List<User_Menu_Response_Dto>();
            var root = rights.Where(d => (d.RparentRid == null || d.RparentRid == "")).OrderBy(d => d.Rno).ToList();//从内存中获取
            root.ForEach(d =>
            {
                data.Add(new User_Menu_Response_Dto
                {
                    name = d.Rname,
                    url = string.IsNullOrEmpty(d.Rurl)?Config.GUID2():d.Rurl, //存在子级则没有url
                    icon=d.Ricon,
                    children = Get_Menus_Children(d.Rid, rights)
                });
            });

            return Result(1, data: data);

        }

        /// <summary>
        /// 获取子级菜单
        /// </summary>
        /// <param name="rid"></param>
        /// <param name="rights"></param>
        /// <returns></returns>
        private List<User_Menu_Response_Dto> Get_Menus_Children(string rid, List<SysRights> rights)
        {
            var children = rights.Where(d => d.RparentRid == rid).OrderBy(d => d.Rno).ToList();
            List<User_Menu_Response_Dto> data = new List<User_Menu_Response_Dto>();
            children.ForEach(d =>
            {
                data.Add(new User_Menu_Response_Dto
                {
                    name = d.Rname,
                    url = string.IsNullOrEmpty(d.Rurl) ? Config.GUID2() : d.Rurl, //存在子级则没有url
                    icon = d.Ricon,
                    children = Get_Menus_Children(d.Rid, rights)
                });
            });
            return data;
        }
        /// <summary>
        /// 获取单个权限详情
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        public Api_Result Get_Curr_RightDetails(Right_Request_Dto dto)
        {
            var iq = _right_IOC._sys_Right_EFCore.QueryAll(d => d.Rid == dto.rid);

            if (!iq.Any()) 
            {
                return Result(0,"参数错误");
            }

            var curr_right = iq.Single();

            Right_Response_Dto data= new Right_Response_Dto() 
            {
                name=curr_right.Rname,
                url = curr_right.Rurl,
                icon = curr_right.Ricon,
                isBan=curr_right.RisBan,
                time=curr_right.RcreateTime,
                explain=curr_right.Rexplain,
                isMenu=curr_right.RisMenu,
                isPublic=curr_right.RisPublic,
                isPublish=curr_right.RisPublish,
                no=curr_right.Rno,               
            };
            return Result(1,data:data);
        }
        /// <summary>
        /// 获取配置
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public Api_Result Get_Right_Config(Right_Request_Dto dto)
        {
            dto.key = dto.key ?? "";
            var iq = _right_IOC._sys_Right_Config_EFCore.QueryAll(d => d.Rcname.Contains(dto.key) && (dto.isPublish == 1 || d.RcisPublish == 1));

            // int total = iq.Count();

            var data = _right_IOC._sys_Right_Config_EFCore.QueryAll(out int total, dto.page, dto.limit, true, d => d.RccreateTime, d => d.Rcname.Contains(dto.key)).
                Select(d => new Right_Config_Response_Dto
                {
                    id = d.Rcid,
                    name = d.Rcname,
                    count = d.Rccount,
                    creatTime = d.RccreateTime,
                    isPublish = d.RcisPublish,
                }).ToList();

            var configids = data.Select(d => d.id).ToList();

            var rcos = _right_IOC._sys_Right_Config_Org_EFCore.QueryAll(d => configids.Contains(d.Rcorcid));

            var deptids = rcos.Select(d => d.RcodeptId).ToList();

            var dutyids = rcos.Select(d => d.RcodutyId).ToList();

            var alldepts = _right_IOC._sys_Dept_EFCore.QueryAll(d => deptids.Contains(d.Did)).ToList();

            var alldutys = _right_IOC._sys_Duties_EFCore.QueryAll(d => dutyids.Contains(d.Did)).ToList();

            data.ForEach(d =>
            {
                var cuur_org = rcos.Where(e => e.Rcorcid == d.id).ToList();
                var curr_deptids = cuur_org.Select(e => e.RcodeptId).ToList();
                var curr_dutyids = cuur_org.Select(e => e.RcodutyId).ToList();
                d.time = d.creatTime.Value.ToString("yyyy/MM/dd HH:mm");
                d.departments = alldepts.Where(e => curr_deptids.Contains(e.Did)).Select(e => e.Dname).ToArray();
                d.duties = alldutys.Where(e => curr_dutyids.Contains(e.Did)).Select(e => e.Dname).ToArray();
            });

            return Result(1, "ok", new
            {
                data,
                total,
            });
        }

       
    }
}
